<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="utf-8">
    <title>layui可编辑table示例</title>
    <meta name="renderer" content="webkit">
    <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
    <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
    <link rel="stylesheet" th:href="@{/lib/layui/css/layui.css}" media="all">
    <link rel="stylesheet" th:href="@{/css/public.css}" media="all">

    <style type="text/css">
        /*您可以将下列样式写入自己的样式表中*/
        .childBody {
            padding: 15px;
        }

        /*layui 元素样式改写*/
        .layui-btn-sm {
            line-height: normal;
            font-size: 12.5px;
        }

        .layui-table-view .layui-table-body {
            min-height: 256px;
        }

        .layui-table-cell .layui-input.layui-unselect {
            height: 30px;
            line-height: 30px;
        }

        /*设置 layui 表格中单元格内容溢出可见样式*/
        .table-overlay .layui-table-view,
        .table-overlay .layui-table-box,
        .table-overlay .layui-table-body {
            overflow: visible;
        }

        .table-overlay .layui-table-cell {
            height: auto;
            overflow: visible;
        }


        /** 数据表格中的input尺寸调整 */
        .layui-table-view .layui-table-cell .layui-input {
            height: 32px;
            line-height: 32px;
        }


        /*文本对齐方式*/
        .text-center {
            text-align: center;
        }
    </style>
</head>
<body class="childBody">

<section class="layui-col-md10" style="margin: 0 auto; float: none;">
    <div class="layui-card">
        <div class="layui-card-header">layui可编辑table示例</div>
        <div class="layui-card-body layui-text">
            <div id="toolbar">
                <div>
                    <button type="button" class="layui-btn layui-btn-sm" data-type="addRow" title="添加一行">
                        <i class="layui-icon layui-icon-add-1"></i> 添加一行
                    </button>
                </div>
            </div>
            <div id="tableRes" class="table-overlay">
                <table id="dataTable" lay-filter="dataTable" class="layui-hide"></table>
            </div>
            <div id="action" class="text-center">
                <button type="button" name="btnSave" class="layui-btn" data-type="save">
                    <i class="layui-icon layui-icon-ok-circle"></i>保存
                </button>
                <button type="reset" name="btnReset" class="layui-btn layui-btn-primary">
                    取消
                </button>
            </div>
        </div>
    </div>

    <!--保存结果输出-->
    <div class="layui-card">
        <div class="layui-card-header">保存结果输出</div>
        <div class="layui-card-body layui-text">
            <blockquote class="layui-elem-quote layui-quote-nm">
                <pre id="jsonResult"><span class="layui-word-aux">请点击“保存”后查看输出信息……</span></pre>
            </blockquote>
        </div>
    </div>
</section>


<script th:src="@{/lib/layui/layui.js}" charset="utf-8"></script>
<script type="text/javascript">
    //准备视图对象
    window.viewObj = {
        tbData: [{
            tempId: new Date().valueOf(),
            type: 2,
            name: '测试项名称',
            state: 1,
            paydate: '20220413',
            paydesc: '测试说明'
        }],
        typeData: [
            {id: 1, name: '分类一'},
            {id: 2, name: '分类二'},
            {id: 3, name: '分类三'},
            {id: 4, name: '分类四'}
        ],
        renderSelectOptions: function (data, settings) {
            settings = settings || {};
            var valueField = settings.valueField || 'value',
                textField = settings.textField || 'text',
                selectedValue = settings.selectedValue || "";
            var html = [];
            for (var i = 0, item; i < data.length; i++) {
                item = data[i];
                html.push('<option value="');
                html.push(item[valueField]);
                html.push('"');
                if (selectedValue && item[valueField] == selectedValue) {
                    html.push(' selected="selected"');
                }
                html.push('>');
                html.push(item[textField]);
                html.push('</option>');
            }
            return html.join('');
        }
    };

    //layui 模块化引用
    layui.use(['jquery', 'table', 'layer', 'laydate'], function () {
        var $ = layui.$, table = layui.table, form = layui.form, laydate = layui.laydate, layer = layui.layer;

        //数据表格实例化
        var tbWidth = $("#tableRes").width();
        var layTableId = "layTable";
        var tableIns = table.render({
            elem: '#dataTable',
            id: layTableId,
            data: viewObj.tbData,
            width: tbWidth,
            page: false,
            limit: Number.MAX_VALUE,
            loading: true,
            even: false, //不开启隔行背景
            cols: [
                [
                    {title: '序号', type: 'numbers'},
                    {
                        field: 'type', title: '分类（type）', templet: function (d) {
                            var options = viewObj.renderSelectOptions(viewObj.typeData, {
                                valueField: "id",
                                textField: "name",
                                selectedValue: d.type
                            });
                            return '<a lay-event="type"></a><select name="type" lay-filter="type"><option value="">请选择分类</option>' + options + '</select>';
                        }
                    },
                    {
                        field: 'name',
                        title: '名称（name）',
                        edit: 'text',
                        style: 'outline: 1px solid #e6e6e6;outline-offset: -6px;overflow: hidden;text-overflow: ellipsis;'
                    },
                    {
                        field: 'paydate', title: '发生日期', width: 130, templet: function (d) {
                            return '<input type="text" name="paydate" id="paydate-' + d.tempId + '" lay-verify="required" placeholder="YYYYMMDD" autocomplete="off" class="layui-input" value="' + d.paydate + '" readonly lay-reqtext="发生日期不得为空>_<">';
                        }
                    },
                    {
                        field: 'paydesc', title: '描述', width: 180, templet: function (d) {
                            return '<input type="text" name="paydesc" id="paydesc-' + d.tempId + '" lay-verify="required" placeholder="描述" autocomplete="off" class="layui-input" value="' + d.paydesc + '" lay-reqtext="描述不得为空>_<">';
                        }
                    },
                    {
                        field: 'state', title: '是否启用（state）', event: 'state', templet: function (d) {
                            var html = ['<input type="checkbox" name="state" lay-skin="switch" lay-text="是|否"'];
                            html.push(d.state > 0 ? ' checked' : '');
                            html.push('/>');
                            return html.join('');
                        }
                    },
                    {
                        field: 'tempId', title: '操作', templet: function (d) {
                            return '<a class="layui-btn layui-btn-xs layui-btn-danger" lay-event="del" lay-id="' + d.tempId + '"><i class="layui-icon layui-icon-delete"></i>移除</a>';
                        }
                    }
                ]
            ],
            done: function (res, curr, count) {
                viewObj.tbData = res.data;

                res.data.forEach(item => {
                    // 初始化laydate
                    laydate.render({
                        elem: '#paydate-' + item.tempId,
                        format: 'yyyyMMdd',
                        //type: 'month', //year time datetime
                        //value: new Date(),
                        //min: 0,
                        //max: lastDay,
                        trigger: 'click', //日期框只能点击选择，不能手动输入
                        done: function (value, date, endDate) {
                            if (!!value) {
                                item.paydate = value;
                            } else {
                                item.paydate = '20220413';
                            }
                            console.log(value);
                        }
                    });

                    // 监听input name="paydesc" 的输入框
                    var paydesc_id = 'paydesc-' + item.tempId;
                    $("#" + paydesc_id + "").on("input", function(e){
                        item.paydesc = e.delegateTarget.value;
                    });
                })

            }
        });

        // 定义事件集合
        var active = {
            // 添加一行
            addRow: function () {
                // var oldData = table.cache[layTableId];
                var oldData = table.getData(layTableId);
                console.log(oldData);

                var newRow = {
                    tempId: new Date().valueOf(),
                    type: null,
                    name: '请填写名称',
                    paydate: '',
                    paydesc: '',
                    state: 0
                };
                oldData.push(newRow);
                tableIns.reload({
                    data: oldData
                });
            },
            // 修改一行
            updateRow: function (obj) {
                // var oldData = table.cache[layTableId];
                var oldData = table.getData(layTableId);
                console.log(oldData);

                for (var i = 0, row; i < oldData.length; i++) {
                    row = oldData[i];
                    if (row.tempId == obj.tempId) {
                        $.extend(oldData[i], obj);
                        return;
                    }
                }
                tableIns.reload({
                    data: oldData
                });
            },
            // 删除一行
            removeEmptyTableCache: function () {
                // var oldData = table.cache[layTableId];
                var oldData = table.getData(layTableId);

                for (var i = 0, row; i < oldData.length; i++) {
                    row = oldData[i];
                    if (!row || !row.tempId) {
                        oldData.splice(i, 1);    //删除一项
                    }
                    continue;
                }
                tableIns.reload({
                    data: oldData
                });
            },
            save: function () {
                // var oldData = table.cache[layTableId];
                var oldData = table.getData(layTableId);

                console.log(oldData);
                for (var i = 0, row; i < oldData.length; i++) {
                    row = oldData[i];
                    if (!row.type) {
                        layer.msg("检查每一行，请选择分类！", {icon: 5}); //提示
                        return;
                    }
                }
                document.getElementById("jsonResult").innerHTML = JSON.stringify(table.cache[layTableId], null, 2);	//使用JSON.stringify() 格式化输出JSON字符串
            }
        }

        // 激活事件
        var activeByType = function (type, arg) {
            // arguments.length表示实际上向函数传入了多少个参数
            if (arguments.length === 2) {
                active[type] ? active[type].call(this, arg) : '';
            } else {
                active[type] ? active[type].call(this) : '';
            }
        }

        // 注册按钮事件
        $('.layui-btn[data-type]').on('click', function () {
            var type = $(this).data('type'); // var type的值其实就等于addRow ，就是data-type里配置的值
            activeByType(type);
        });

        // 监听select下拉选中事件
        form.on('select(type)', function (data) {
            var elem = data.elem; //得到select原始DOM对象
            $(elem).prev("a[lay-event='type']").trigger("click");
        });

        // 监听table工具条
        table.on('tool(dataTable)', function (obj) {
            var data = obj.data,
                event = obj.event,
                tr = obj.tr; // 获得当前行 tr 的DOM对象;
            console.log(data);

            switch (event) {
                case "type":
                    var select = tr.find("select[name='type']");
                    if (select) {
                        var selectedVal = select.val();
                        if (!selectedVal) {
                            layer.tips("请选择一个分类", select.next('.layui-form-select'), {tips: [3, '#FF5722']}); //吸附提示
                        }
                        console.log(selectedVal);
                        $.extend(obj.data, {'type': selectedVal});
                        activeByType('updateRow', obj.data);	//更新行记录对象
                    }
                    break;
                case "state":
                    var stateVal = tr.find("input[name='state']").prop('checked') ? 1 : 0;
                    $.extend(obj.data, {'state': stateVal})
                    activeByType('updateRow', obj.data);	//更新行记录对象
                    break;
                case "del":
                    layer.confirm('真的删除行么？', function (index) {
                        obj.del(); //删除对应行（tr）的DOM结构，并更新缓存
                        layer.close(index);
                        activeByType('removeEmptyTableCache');
                    });
                    break;
            }
        });
    });
</script>


</body>
</html>